package com.offics.loan.infrastructure.persistence;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.offics.loan.domain.entity.RepaymentRecord;
import com.offics.loan.domain.repository.RepaymentRecordRepository;
import com.offics.loan.infrastructure.persistence.mapper.RepaymentRecordMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Optional;
import java.util.Random;

/**
 * 还款记录仓储实现类
 */
@Repository
@RequiredArgsConstructor
public class RepaymentRecordRepositoryImpl extends ServiceImpl<RepaymentRecordMapper, RepaymentRecord> implements RepaymentRecordRepository {

    private final RepaymentRecordMapper repaymentRecordMapper;

    @Override
    public Optional<RepaymentRecord> findById(Long id) {
        return Optional.ofNullable(repaymentRecordMapper.selectById(id));
    }

    @Override
    public Optional<RepaymentRecord> findByTradeNo(String tradeNo) {
        LambdaQueryWrapper<RepaymentRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentRecord::getTradeNo, tradeNo);
        return Optional.ofNullable(repaymentRecordMapper.selectOne(wrapper));
    }

    @Override
    public List<RepaymentRecord> findByLoanId(Long loanId) {
        LambdaQueryWrapper<RepaymentRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentRecord::getLoanId, loanId);
        wrapper.orderByDesc(RepaymentRecord::getRepayTime);
        return repaymentRecordMapper.selectList(wrapper);
    }

    @Override
    public List<RepaymentRecord> findByUserId(Long userId) {
        LambdaQueryWrapper<RepaymentRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentRecord::getUserId, userId);
        wrapper.orderByDesc(RepaymentRecord::getRepayTime);
        return repaymentRecordMapper.selectList(wrapper);
    }

    @Override
    public List<RepaymentRecord> findByRepaymentPlanId(Long repaymentPlanId) {
        LambdaQueryWrapper<RepaymentRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentRecord::getRepaymentPlanId, repaymentPlanId);
        wrapper.orderByDesc(RepaymentRecord::getRepayTime);
        return repaymentRecordMapper.selectList(wrapper);
    }

    @Override
    public List<RepaymentRecord> findByUserIdAndStatus(Long userId, Integer status) {
        LambdaQueryWrapper<RepaymentRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentRecord::getUserId, userId);
        wrapper.eq(RepaymentRecord::getStatus, status);
        wrapper.orderByDesc(RepaymentRecord::getRepayTime);
        return repaymentRecordMapper.selectList(wrapper);
    }

    @Override
    public IPage<RepaymentRecord> findPage(IPage<RepaymentRecord> page, Long userId, Long loanId, Integer status) {
        LambdaQueryWrapper<RepaymentRecord> wrapper = new LambdaQueryWrapper<>();
        if (userId != null) {
            wrapper.eq(RepaymentRecord::getUserId, userId);
        }
        if (loanId != null) {
            wrapper.eq(RepaymentRecord::getLoanId, loanId);
        }
        if (status != null) {
            wrapper.eq(RepaymentRecord::getStatus, status);
        }
        wrapper.orderByDesc(RepaymentRecord::getRepayTime);
        return repaymentRecordMapper.selectPage(page, wrapper);
    }

    @Override
    public boolean save(RepaymentRecord repaymentRecord) {
        return repaymentRecordMapper.insert(repaymentRecord) > 0;
    }

    @Override
    public RepaymentRecord saveAndReturn(RepaymentRecord repaymentRecord) {
        if (save(repaymentRecord)) {
            return repaymentRecord;
        }
        return null;
    }

    @Override
    public boolean update(RepaymentRecord repaymentRecord) {
        return repaymentRecordMapper.updateById(repaymentRecord) > 0;
    }

    @Override
    public boolean deleteById(Long id) {
        return repaymentRecordMapper.deleteById(id) > 0;
    }

    @Override
    public boolean deleteByLoanId(Long loanId) {
        LambdaQueryWrapper<RepaymentRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentRecord::getLoanId, loanId);
        return repaymentRecordMapper.delete(wrapper) > 0;
    }

    @Override
    public boolean deleteByUserId(Long userId) {
        LambdaQueryWrapper<RepaymentRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentRecord::getUserId, userId);
        return repaymentRecordMapper.delete(wrapper) > 0;
    }

    @Override
    public boolean deleteByRepaymentPlanId(Long repaymentPlanId) {
        LambdaQueryWrapper<RepaymentRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentRecord::getRepaymentPlanId, repaymentPlanId);
        return repaymentRecordMapper.delete(wrapper) > 0;
    }

    @Override
    public String generateTradeNo() {
        // 生成交易编号：TRADE + 年月日时分秒 + 4位随机数
        String dateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String randomNum = String.format("%04d", new Random().nextInt(10000));
        return "TRADE" + dateTime + randomNum;
    }

    @Override
    public boolean existsByTradeNo(String tradeNo) {
        LambdaQueryWrapper<RepaymentRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepaymentRecord::getTradeNo, tradeNo);
        return repaymentRecordMapper.selectCount(wrapper) > 0;
    }
}
